#! /usr/bin/env python
#coding=utf-8
from uliweb import expose
from sqlalchemy import *
from uliweb.orm import *
from uliweb.utils.pyini import Ini
from sqlalchemy.sql import select
from sqlalchemy.sql import and_, or_, not_
import time, sys
sys.path.insert(0, '../apps')

from departments.models import *
from myuser.models import *

from systems.models import *
from requirements.models import *
from assignments.models import *

from charts.models import *
from tasks.models import *


import datetime
from datetime import date
from get_month_quarter import *
#from __future__ import division



#from uliweb.core.SimpleFrame import Dispatcher
#settings = {'ORM/DEBUG_LOG':True, 'ORM/AUTO_CREATE':False,'ORM/CONNECTION':'sqlite:///../database.db'}
#app = Dispatcher(apps_dir='../apps', start=False, default_settings=settings)

#meta = MetaData(db)
#db.metadata.reflect()
db = get_db_connection()
def get_task_plan_delay(row,first_day,last_day):
    
    req_planexecute = get_model('planexecute')
    req_plan = get_model('plan')
    
    settings = Ini('../apps/settings.ini')
    milestone_buffer = dict(settings.PARA.MILESTONE_DELAY_DAY)
    
    weight_delay = 0
    weight_total = 0
    delay_stat = ''
    day_buffer = milestone_buffer.get('buffer')
    
    task = row.id
    dev_task = row.task_id
    plan_total = select([func.sum(req_plan.c.weight)],
                         and_(req_plan.c.task == task))
    rs_plan_total = plan_total.execute()
    for row_p in rs_plan_total:
        if row_p[0]:
            weight_total = row_p[0]
    
    delay = select([req_plan.c.title,
                    req_plan.c.type,
                    req_plan.c.begin_date,
                    req_plan.c.end_date,
                    req_planexecute.c.finish_begin_date,
                    req_planexecute.c.finish_end_date,
                    req_plan.c.weight],
                    and_(req_planexecute.c.task == task,
                            req_plan.c.id == req_planexecute.c.plan,
                            or_(and_(req_plan.c.type == '1',
                                    or_(req_plan.c.begin_date != None,
                                        req_plan.c.end_date != None)
                                        ),
                                and_(req_plan.c.type == '2',
                                    req_plan.c.end_date != None
                                     )
                                )
                        ))
    
    #      now = datetime.datetime.now()
    #      print 'two for begin',now
#    print 'delay',delay
    delay_rs = delay.execute()
    for row_d in delay_rs:
    #          dev_task,devid,planid,plan_name,plan_date = row_d
        plan_name,type,begin_date,end_date,finish_begin_date,finish_end_date,weight = row_d
    #      delay = select([req_plan.c.id,
    #                      req_plan.c.name,
    #                      req_plan.c.plan_date,
    #                      req_plan.c.flag],
    #                      and_(req_plan.c.task == task_head,
    ##                          req_plan.c.plan_date <= last_day
    #                          req_plan.c.plan_date != None
    #                          ))
    #      
    ##      now = datetime.datetime.now()
    ##      print 'two for begin',now
    #     
    #      delay_rs = delay.execute()
    #      for row_d in delay_rs:
    ##          dev_task,devid,planid,plan_name,plan_date = row_d
    #          planid,plan_name,plan_date,flag = row_d
    #          delay_milestone = select([func.max(tasks_milestone.c.finish_date)],
    #                                  and_(tasks_milestone.c.task == task,
    #                                      tasks_milestone.c.milestone_plan == planid))
    #          delay_milestone_rs = delay_milestone.execute()
    #          #初始化finish_date
    #          finish_date = None
        
    #          weight = milestone_weight.get(flag,weight_default)
        #累计任务里程碑总权重
#        weight_total += weight
        
    #          for row_m in delay_milestone_rs:
    #              finish_date, = row_m
            #print 'finish_date',finish_date
    
        if type == '2' and end_date and (end_date <= last_day and (not finish_end_date or finish_end_date>= end_date)):    
            if finish_end_date and ((end_date >=first_day and finish_end_date == end_date) or (end_date < first_day)):
                continue
            else:
                #累计延迟15%的里程碑权重,函数datediff计算两个日期之间的天数
                if datediff(row.begin_time,row.end_time)!=0 and float(datediff(end_date,last_day))/datediff(row.begin_time,row.end_time) >= day_buffer:
                    weight_delay += weight                    
                if finish_end_date:
#                    print '1vvvvvvvvv',dev_task,end_date,finish_end_date
                    delay_stat = delay_stat+str(dev_task)+'-'+plan_name+'('+u'里程碑计划完成时间:'+str(end_date)[0:10]+'|'+u'实际完成时间:'+str(finish_end_date)[0:10]+')'+';\n '
                else:
#                    print '1dddddddddd',dev_task,end_date,finish_end_date
                    delay_stat = delay_stat+str(dev_task)+'-'+plan_name+'('+u'里程碑计划完成时间:'+str(end_date)[0:10]+'|'+u'实际完成时间:'+u'未填写'+')'+';\n '
        elif type == '2' and end_date and finish_end_date and end_date>=first_day and end_date <= last_day and finish_end_date<end_date:
            if datediff(row.begin_time,row.end_time)!=0 and float(datediff(end_date,finish_end_date))/datediff(row.begin_time,row.end_time) >= day_buffer:
                weight_delay += weight 
#            print '1wwwwwwwwww',dev_task,end_date,finish_end_date
            delay_stat = delay_stat+str(dev_task)+'-'+plan_name+'('+u'里程碑计划完成时间:'+str(end_date)[0:10]+'|'+u'实际完成时间:'+str(finish_end_date)[0:10]+')'+';\n '
        if type == '1' and begin_date and (begin_date <= last_day and (not finish_begin_date or finish_begin_date >= begin_date)):    
            if finish_begin_date and ((begin_date >=first_day and finish_begin_date == begin_date) or (begin_date < first_day)):
                pass
            else:
                #累计延迟15%的里程碑权重,函数datediff计算两个日期之间的天数
#                print 'begin_date,last_day',begin_date,last_day,row.begin_time,row.end_time,row.id
                if datediff(row.begin_time,row.end_time)!=0 and float(datediff(begin_date,last_day))/datediff(row.begin_time,row.end_time) >= day_buffer:
                    weight_delay += weight
                if finish_begin_date:
#                    print '2vvvvvvvvv',dev_task,begin_date,finish_begin_date
                    delay_stat = delay_stat+str(dev_task)+'-'+plan_name+'('+u'计划开始时间:'+str(begin_date)[0:10]+'|'+u'实际完成时间:'+str(finish_begin_date)[0:10]+')'+';\n '
                else:
#                    print '2ddddddddd',dev_task,begin_date,finish_begin_date
                    delay_stat = delay_stat+str(dev_task)+'-'+plan_name+'('+u'计划开始时间:'+str(begin_date)[0:10]+'|'+u'实际完成时间:'+u'未填写'+')'+';\n '
        elif type == '1' and begin_date and finish_begin_date and begin_date >= first_day and begin_date <= last_day and finish_begin_date<begin_date:
            if datediff(row.begin_time,row.end_time)!=0 and float(datediff(begin_date,finish_begin_date))/datediff(row.begin_time,row.end_time) >= day_buffer:
                weight_delay += weight
#            print '2wwwwwwwwww',dev_task,begin_date,finish_begin_date
            delay_stat = delay_stat+str(dev_task)+'-'+plan_name+'('+u'计划开始时间:'+str(begin_date)[0:10]+'|'+u'实际完成时间:'+str(finish_begin_date)[0:10]+')'+';\n '
        if type == '1' and end_date and (end_date <= last_day and (not finish_end_date or finish_end_date >= end_date)):    
            if finish_end_date and ((end_date >=first_day and finish_end_date == end_date) or (end_date < first_day)):
                continue
            else:
                #累计延迟15%的里程碑权重,函数datediff计算两个日期之间的天数
                if datediff(row.begin_time,row.end_time)!=0 and float(datediff(end_date,last_day))/datediff(row.begin_time,row.end_time) >= day_buffer:
                    weight_delay += weight                    
                if finish_end_date:
#                    print '3vvvvvvvv',dev_task,end_date,finish_end_date
                    delay_stat = delay_stat+str(dev_task)+'-'+plan_name+'('+u'计划完成时间:'+str(end_date)[0:10]+'|'+u'实际完成时间:'+str(finish_end_date)[0:10]+')'+';\n '
                else:
#                    print '3ddddddddd',dev_task,end_date,finish_end_date
                    delay_stat = delay_stat+str(dev_task)+'-'+plan_name+'('+u'计划完成时间:'+str(end_date)[0:10]+'|'+u'实际完成时间:'+u'未填写'+')'+';\n '
        elif type == '1' and end_date and finish_end_date and end_date >=first_day and end_date <= last_day and finish_end_date<end_date:
            if datediff(row.begin_time,row.end_time)!=0 and float(datediff(end_date,finish_end_date))/datediff(row.begin_time,row.end_time) >= day_buffer:
                weight_delay += weight
#            print '3wwwwwwwwww',dev_task,end_date,finish_end_date
            delay_stat = delay_stat+str(dev_task)+'-'+plan_name+'('+u'计划完成时间:'+str(end_date)[0:10]+'|'+u'实际完成时间:'+str(finish_end_date)[0:10]+')'+';\n '
        
    return delay_stat,weight_delay,weight_total
    
def get_tasks_develop_report_detail(month_first_day,month_last_day,report_type):
    
    #从settings.ini获取里程碑计划权重
    settings = Ini('../apps/settings.ini')
    milestone_weight = dict(settings.PARA.MILESTONE_WEIGHT)
    milestone_buffer = dict(settings.PARA.MILESTONE_DELAY_DAY)
    
    day_buffer = milestone_buffer.get(buffer)

    req_task = get_model('tasks_develop')
    req_detail = get_model('tasks_develop_report_detail')
#    req_plan = get_model('milestone_plan')
#    tasks_milestone = get_model('tasks_milestone')
    req_planchange = get_model('planchange')
    req_planexecute = get_model('planexecute')
    req_plan = get_model('plan')
    Requirement = get_model('requirement')
    
            
    #获取本周末日期
    nineday = datetime.timedelta(days=9)
#    today = datetime.date.today()

    #first_day,last_day = get_week()
    last_day = month_last_day
    first_day = month_first_day
    report_type = report_type

    obj_task =  req_task.filter(or_(and_(req_task.c.stage != 'FN',
                                         req_task.c.status != '4',
                                         req_task.c.status != '5',
                                         req_task.c.stage != '00'),
                                    and_(req_task.c.stage == '00',
                                         req_task.c.begin_time <= last_day),
                                    and_(req_task.c.modified_date >= first_day,
                                         req_task.c.stage == 'FN')))
#    res_task_rs = res_task.execute()
    #print 'obj_ass',obj_ass
    data={}
    
#    now = datetime.datetime.now()
#    print 'first for begin',now

    #获取普通里程碑权重
#    weight_default = milestone_weight.get('default',0)
#    print 'weight_default',weight_default
    
    for row in obj_task:
#        ass_id,ass_name,kfzx,tx,type,stage,release_date,begin_date,end_date,modified_date,status,delay_classes,delay_reason,advanced_if,risk_if,risk_reason,systems,requirements = row
#        ass_id,ass_name,kfzx,type,stage,release_date,begin_date,end_date,modified_date,status,delay_classes,delay_reason,advanced_if,risk_if,risk_reason, = row
#        print 'row',row
        y = str(row.id)
        data[y] = {}
        data[y]['task'] = row.id
        data[y]['task_id'] = row.task_id
        data[y]['name'] = row.name
        data[y]['task_sys'] = row._task_sys_
        data[y]['task_type'] = row.task_type
        data[y]['requirement'] = row._requirement_
        data[y]['assignment'] = row._assignment_
        data[y]['begin_time'] = row.begin_time
        data[y]['end_time'] = row.end_time
        data[y]['stage'] = row.stage
        data[y]['stage_enterTime'] = row.stage_enterTime
        data[y]['version_headerId'] = row._version_headerId_
        data[y]['status'] = row.status
        data[y]['kfzx'] = row._kfzx_
        data[y]['version_date'] = row.version_date
        if row._requirement_ and Requirement.get(row._requirement_):
            data[y]['tx'] = row.requirement._tx_
        else:
            data[y]['tx'] = ''
        
        data[y]['delay_classes'] = row.delay_classes
        data[y]['delay_reason'] = row.delay_reason
        data[y]['memo'] = row.memo
        data[y]['risk_if'] = row.risk_if
        data[y]['risk_reason'] = row.risk_reason
        data[y]['delay_milestone'] = ''
        data[y]['milestone_delay_num'] = 0
        data[y]['milestone_change_num'] = 0
        data[y]['milestone_total_num'] = 0
        data[y]['change_milestone'] = ''
        
#        data[y]['systems'] = systems
#任务实施中定义为任务阶段不是完成或阶段为未开时而任务开始时间，20110315
        if (row.stage != 'FN' and row.stage != '00') or (row.stage == '00' and row.begin_time <= last_day):#判断阶段为完成或未开时，则任务在实施中
            data[y]['t_implement'] = 1
        else:
            data[y]['t_implement'] = 0
            
        if row.stage == 'FN':#阶段为完成
            data[y]['t_finish'] = 1
        else:
            data[y]['t_finish'] = 0
            
        task = row.id
        
        if row.version_headerId != None:
            task_head = row._version_headerId_
        else:
            task_head = row.id
        dev_task = row.task_id
        delay_stat = ''

        #任务延迟率初始化
#        task_milestone_rate = 0
        weight_total = 0
        weight_delay = 0
        milestone_change = 0
        change_milestone = ''
        
        #获取任务里程碑或计划延迟情况
        delay_stat,weight_delay,weight_total = get_task_plan_delay(row,first_day,last_day)
            
        data[y]['delay_milestone'] = delay_stat        
        if (delay_stat or (row.end_time < first_day and row.status != '3' and row.stage != 'FN')) and (row.status != '4' or row.status != '5' ):
            data[y]['t_delay'] = 1
        else:
            data[y]['t_delay'] = 0
        
        #计算任务里程碑延迟权重合计数
#        if weight_total != 0:
        data[y]['milestone_delay_num'] = weight_delay#/weight_total

            

#        if row.end_date <= today and row.stage != 'FN' and row.stage != '16' and row.status != '4' and row.status != '5':
#           data[y]['t_delay'] = 1
#        else:
#           data[y]['t_delay'] = 0

        if row.status == '4' or row.status == '5':#任务书状态为暂停或终止
            data[y]['t_status'] = 1
        else:
            data[y]['t_status'] = 0
        #判断是否本周末投产
        if report_type == '1':
            monday = first_day + nineday
            #根据需求将下周拟投产版本范围延迟1天
            sunday = last_day + nineday + datetime.timedelta(days=1)
        elif report_type == '2':
            monday,sunday = get_next_month()
        elif report_type == '3':
            monday,sunday = get_next_quarter()        
        
#        if not row.version_date:
#            print 'ccccccccccccc',row.task_id,monday,sunday
        if row.version_date and row.version_date >=monday and row.version_date <= sunday:
            data[y]['t_version'] = 1
        else:
            data[y]['t_version'] = 0
        data[y]['report_date'] = last_day
        data[y]['report_type'] = report_type
        
        #计算任务里程碑变更率
        sql_change = select([func.distinct(req_planchange.c.plan_id),
                             req_planchange.c.weight,
                             func.max(req_planchange.c.modified_date),
                             req_plan.c.title],
                             and_(req_plan.c.id == req_planchange.c.plan_id,
                                  req_planchange.c.task_id == task,
                                  req_planchange.c.modified_date >= first_day,
#                                  milestone_details.c.modified_date >= row.begin_time,
                                  req_planchange.c.modified_date <= last_day)
                                ).group_by(req_planchange.c.plan_id)
         
        rs_sql_change = sql_change.execute()
        for row3 in rs_sql_change:
            planid,weight,modified_date,planname = row3
            if modified_date == None:
                continue
#            weight = milestone_weight.get(flag,weight_default)
            #函数datediff计算两个日期之间的天数
#            print 'wwwwwwwwwwwwwwww',planid,flag,modified_date
            modified_date = datetimetodate(modified_date)
            
            if modified_date < row.end_time and modified_date > row.begin_time:
                if datediff(row.begin_time,row.end_time)!=0 :
                    milestone_change += weight*(float(datediff(row.begin_time,modified_date))/datediff(row.begin_time,row.end_time))
#                print 'ffffffffffffffff-l',row.id,weight,float(datediff(row.begin_time,modified_date)),datediff(row.begin_time,row.end_time),'over'
                change_milestone = change_milestone + planname + '-' + u'变更时间:' + str(modified_date) + '; \n'
                
#        if milestone_change>weight_total:
#            print 'dddddddddddd',row.id,row.task_id,milestone_change,weight_total
#        if weight_total != 0:
        data[y]['milestone_change_num'] = milestone_change#/weight_total
        data[y]['change_milestone'] = change_milestone
        data[y]['milestone_total_num'] = weight_total
#        data[y]['requirements'] = requirements
#        ids = row.systems.ids()
#        req_detail.systems.add(*ids)
#        print 'data',data
#        now = datetime.datetime.now()
#        print 'first for end',now
        
    return data


